package com.tanhua.server.service;

import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.tanhua.autoconfig.templates.OssTemplate;
import com.tanhua.domain.db.User;
import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.mongo.Comment;
import com.tanhua.domain.mongo.Publish;
import com.tanhua.domain.mongo.Video;
import com.tanhua.dubbo.api.db.UserInfoApi;
import com.tanhua.dubbo.api.mongo.CommentApi;
import com.tanhua.dubbo.api.mongo.VideoApi;
import com.tanhua.server.interceptors.UserHolder;
import com.tanhua.server.utils.RelativeDateFormat;
import com.tanhua.vo.Movements;
import com.tanhua.vo.PageResult;
import com.tanhua.vo.VideoVo;
import org.apache.commons.io.FileUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.bson.types.ObjectId;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class VideosService {
    @Reference
    private CommentApi commentApi;
    @Reference
    private VideoApi videoApi;
    @Autowired
    private OssTemplate ossTemplate;

    @Autowired
    private FastFileStorageClient fileStorageClient;

    @Autowired
    private FdfsWebServer fdfsWebServer;

    @Reference
    private UserInfoApi userInfoApi;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @CacheEvict(cacheNames ="videosList",allEntries = true)
    public ResponseEntity saveVideos(MultipartFile videoThumbnail, MultipartFile videoFile) throws Exception {
//        构建Video对象
        Video video = new Video();

        String picUrl = ossTemplate.upload(videoThumbnail.getOriginalFilename(), videoThumbnail.getInputStream());
        video.setPicUrl(picUrl); //封面

//        InputStream inputStream 文件流, long fileSize 文件大小, String fileExtName 文件的扩展名, Set< MetaData > metaDataSet 文件相关属性
        String fileName= videoFile.getOriginalFilename();
        String extName = fileName.substring(fileName.lastIndexOf(".")+1);
        StorePath storePath = fileStorageClient.uploadFile(videoFile.getInputStream() , videoFile.getSize(), extName, null);
        String videoUrl = fdfsWebServer.getWebServerUrl()+storePath.getFullPath();
        video.setVideoUrl(videoUrl); //小视频
        video.setText("我这么好看，这么好看怎么办"); //TODO 这个值应该是手机端传入的 ，但是没有传
        video.setUserId(UserHolder.getUserId());

        videoApi.save(video);

        return ResponseEntity.ok(null);
    }

    @Cacheable(cacheNames = "videosList",key = "#page+'_'+#pagesize")
//    ResponseEntity没有实现序列化接口，所以不能缓存 把ResponseEntity改成PageResult
    public PageResult videosList(Integer page, Integer pagesize) {
 //        TODO 现在我们直接查询小视频那张表 按理来说我们应该查询推荐小视频表 ，等我们大数据推送功能完成后再查询推荐数据
        PageResult pageResult = videoApi.queryVideoList(page,pagesize);
        List<Video> items = (List<Video>) pageResult.getItems();

        System.out.println("数据从数据库中获取的");
        List<VideoVo> list = new ArrayList<>();
        for (Video video : items) {
            Long userId = video.getUserId();
            UserInfo userInfo = userInfoApi.findById(userId);
            if(userInfo==null){  //为了防止垃圾数据
                continue;
            }
            VideoVo videoVo = new VideoVo();

            BeanUtils.copyProperties(video,videoVo);
            videoVo.setId(video.getId().toString());
            videoVo.setCover(video.getPicUrl());
            videoVo.setSignature(video.getText());

            BeanUtils.copyProperties(userInfo,videoVo);

            if(redisTemplate.hasKey("quanzi_publish_like_"+UserHolder.getUserId()+"_"+video.getId().toString())){
                videoVo.setHasLiked(1); //是否点赞
            }else{
                videoVo.setHasLiked(0); //是否点赞
            }


            if(redisTemplate.hasKey("follow_user_"+UserHolder.getUserId()+"_"+video.getUserId())){
                videoVo.setHasFocus(1); //是否关注视频的作者
            }else{
                videoVo.setHasFocus(0); //是否关注
            }
            list.add(videoVo);

        }
        pageResult.setItems(list);
        return pageResult;
    }

    public ResponseEntity userFocus(Long followUserId) {

        videoApi.saveFollowUser(UserHolder.getUserId(),followUserId);
        redisTemplate.boundValueOps("follow_user_"+UserHolder.getUserId()+"_"+followUserId).set("");
        return ResponseEntity.ok(null);

    }

    public ResponseEntity userUnFocus(Long followUserId) {
        videoApi.removeFollowUser(UserHolder.getUserId(),followUserId);
        redisTemplate.delete("follow_user_"+UserHolder.getUserId()+"_"+followUserId);
        return ResponseEntity.ok(null);
    }
    //视频点赞
    public ResponseEntity likeVideos(String publishId, Integer pubType) {
        Long userId = UserHolder.getUserId();

        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(publishId));
        comment.setCommentType(1);  //评论类型，1-点赞，2-评论，3-喜欢
        comment.setPubType(pubType);    //评论内容类型： 1-对圈子动态操作 2-对视频操作 3-对评论操作
        comment.setContent(""); //这是点赞的操作，所以评论内容是空的
        comment.setUserId(userId);

        Integer count = commentApi.save(comment);
//        当前登录人已对这个视频点赞了 记录到redis中
        redisTemplate.boundValueOps("Videos_publish_like_"+userId+"_"+publishId).set("");
        return ResponseEntity.ok(count);

    }

    public ResponseEntity likeVideosdislike(String publishId, Integer pubType) {
        Long userId = UserHolder.getUserId();

        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(publishId));
        comment.setCommentType(1);  //评论类型，1-点赞，2-评论，3-喜欢
        comment.setPubType(pubType);    //评论内容类型： 1-对圈子动态操作 2-对视频操作 3-对评论操作
        comment.setContent(""); //这是点赞的操作，所以评论内容是空的
        comment.setUserId(userId);

        Integer count = commentApi.remove(comment);
//        当前登录人已对这个视频点赞了 记录到redis中
        redisTemplate.boundValueOps("Videos_publish_like_"+userId+"_"+publishId).set("");
        return ResponseEntity.ok(count);

    }
    //根据id查询视频
    public ResponseEntity queryMovementsById(String publishId) {
        Publish publish = videoApi.findById(publishId);
        Long userId = publish.getUserId();
        UserInfo userInfo = userInfoApi.findById(userId);
        Movements movements = publishAndUserInfoToMovements(publish, userInfo);
        return ResponseEntity.ok(movements);
    }
    //公共代码
    private Movements publishAndUserInfoToMovements(Publish publish, UserInfo userInfo) {
        Movements movements = new Movements();
        BeanUtils.copyProperties(userInfo, movements);
        if (userInfo.getTags() != null) {
            movements.setTags(userInfo.getTags().split(","));
        }
        BeanUtils.copyProperties(publish, movements);
        movements.setId(publish.getId().toString());
        movements.setImageContent(publish.getMedias().toArray(new String[]{}));
        movements.setDistance("500米");
        movements.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));

        if(redisTemplate.hasKey("Videos_publish_like_"+UserHolder.getUserId()+"_"+publish.getId().toString())){
            movements.setHasLiked(1); //代表当前登录人对这个动态已点赞
        }else{
            movements.setHasLiked(0); //代表当前登录人对这个动态未点赞
        }

        if(redisTemplate.hasKey("Videos_publish_like_"+UserHolder.getUserId()+"_"+publish.getId().toString())){
            movements.setHasLoved(1); //代表当前登录人对这个动态已喜欢
        }else{
            movements.setHasLoved(0); //代表当前登录人对这个动态未喜欢
        }

        return movements;
    }
//小视频评论点赞取消
    public ResponseEntity dislikeVideosComments(String publishId, Integer pubType) {
        Long userId = UserHolder.getUserId();

        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(publishId));
        comment.setCommentType(1);  //评论类型，1-点赞，2-评论，3-喜欢
        comment.setPubType(pubType);    //评论内容类型： 1-对圈子动态操作 2-对视频操作 3-对评论操作
        comment.setContent(""); //这是点赞的操作，所以评论内容是空的
        comment.setUserId(userId);
        //返回的是这个圈子动态的点赞数量
        Integer count = commentApi.remove(comment);
//        当前登录人已对这个动态点赞了 记录到redis中
        redisTemplate.boundValueOps("Videos_publish_like_"+userId+"_"+publishId).set("");
        return ResponseEntity.ok(null);
    }
//小视频评论点赞
    public ResponseEntity likeVideosComments(String publishId, Integer pubType) {
        Long userId = UserHolder.getUserId();

        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(publishId));
        comment.setCommentType(1);  //评论类型，1-点赞，2-评论，3-喜欢
        comment.setPubType(pubType);    //评论内容类型： 1-对圈子动态操作 2-对视频操作 3-对评论操作
        comment.setContent(""); //这是点赞的操作，所以评论内容是空的
        comment.setUserId(userId);
        //返回的是这个圈子动态的点赞数量
        Integer count = commentApi.save(comment);
//        当前登录人已对这个动态点赞了 记录到redis中
        redisTemplate.boundValueOps("Videos_publish_like_"+userId+"_"+publishId).set("");
        return ResponseEntity.ok(null);
    }
}
